#include "ShaderSettings.txt"
#include "common.h"
#include "mblur.h"

struct v2p
{
  float4 tc0: 		TEXCOORD0;	// Center
  float4 tc1: 		TEXCOORD1;	// LT 		 
  float4 tc2: 		TEXCOORD2;	// RB
  float4 tc3: 		TEXCOORD3;	// RT 
  float4 tc4: 		TEXCOORD4;	// LB
  float4 tc5:		TEXCOORD5;	// Left	/ Right	
  float4 tc6:		TEXCOORD6;	// Top  / Bottom 
};

uniform sampler2D s_distort;
uniform half4 e_barrier;
uniform half4 e_weights;
uniform half4 e_kernel;

#include "aa.h"
#include "blur.h"
#include "nightvision.h"

#define EPSDEPTH 0.001
half4 main(v2p I):COLOR {
#ifdef USE_DISTORT
half depth=tex2D(s_position,I.tc0).z;
half4 distort=tex2D(s_distort, I.tc0);
half2 offset=(distort.xy-.5h)*def_distort;
float2 center=I.tc0+offset;
half depth_x=tex2D (s_position,center).z;
if ((depth_x+EPSDEPTH)<depth) center=I.tc0;
#else
float2 center=I.tc0;
#endif

half3 img=tex2D(s_image,center);
half4 bloom=tex2D(s_bloom,center);

#ifdef AA
float3 result = aa(I);
#else
float3 result = img.rgb;
#endif

#ifdef IMPROVED_MBLUR
float z=tex2D(s_position,I.tc0).z;
if (z>START_DIST && z<FINAL_DIST) {img=mblur(center,tex2D(s_position,I.tc0),result);}
else { img=result;}
#else
img=mblur(center,tex2D(s_position,I.tc0),result);
#endif

#ifdef USE_DISTORT
half3 blurred=bloom*def_hdr;
img=lerp(img,blurred,distort.z);
#endif
float2 cent=I.tc0;
float dep=tex2D(s_position,cent).z;
float origDep = dep;
float fov = e_weights.y * 1000;
float mycof=MAXCOF;
float myMINDIST = MINDIST;
float myMAXDIST = MAXDIST;
float myMAXNEAR = MAXNEAR;
float myMINNEAR = MINNEAR;
float targetDist = (fov < ZOOM_FOV) ? tex2D(s_position,ZOOM_CENTER).z : tex2D(s_position,DDOF_CENTER).z;
float realTargetDist = targetDist;
if (targetDist <= myMAXNEAR) myMAXNEAR = targetDist;

#ifdef DDOF
if (targetDist < MAXDIST && targetDist < DDOF_MAXBARRIER)
{
	mycof = DDOF_MAXCOF;
	myMINDIST = targetDist + DDOF_MINDIST_ADD;	
	float maxFactor = (targetDist < DDOF_MAXDIST) ? 1 : (targetDist / DDOF_MAXDIST);
	myMAXDIST = myMINDIST * DDOF_MAXDIST_FACTOR * maxFactor;
}
#endif

float colorFactor = e_barrier.y * 100;

#ifdef DDOF_DEBUG
bool debug = true;
#else
bool debug = false;
#endif

if (dep <= myMAXNEAR && dep > myMINNEAR)
{
	dep = (1 - (dep-myMINNEAR)/(myMAXNEAR-myMINNEAR) ) * myMAXDIST;
	mycof = MAXCOF_NEAR;
	if (debug && e_barrier.z > 0.7) { img.x *= colorFactor; img.y *= colorFactor; }  // DEBUG YELLOW
}
else if (dep > myMAXNEAR && dep < realTargetDist-DDOF_MINDIST_ADD && dep > DDOF_MINDIST)
{	
	dep = saturate( 1 - (dep-DDOF_MINDIST)/(realTargetDist-DDOF_MINDIST_ADD-DDOF_MINDIST) )  * MAXDIST;
	#ifdef ZOOM_DDOF
	if (fov < ZOOM_FOV)	mycof = DDOF_MAXCOF_NEAR; else mycof = 0;
	#else
	mycof = 0;
	#endif
	
	myMAXDIST = MAXDIST;
	
	if (debug && e_barrier.x == 0.8)
	{
		if (dep > 300) img.x *= colorFactor; // RED
		else if (dep > 200) img.y *= colorFactor; //GREEN
		else if (dep > 100) img.z *= colorFactor; // BLUE
		else if (dep > 50) { img.x *= colorFactor; img.y *= colorFactor; }  // DEBUG YELLOW
		else if (dep > 10) { img.x *= colorFactor; img.z *= colorFactor; }  // DEBUG MAGENTA
		else if (dep > 0)  { img.y *= colorFactor; img.z *= colorFactor; }  // DEBUG CYAN
	}
	
	if (debug && e_barrier.z > 0.8) { img.x *= colorFactor; img.z *= colorFactor; }  // DEBUG MAGENTA	
}
else if (dep > myMAXNEAR && dep < realTargetDist-DDOF_MINDIST_ADD && dep <= DDOF_MINDIST)
{
	dep = saturate( (dep-myMAXNEAR)/(DDOF_MINDIST-myMAXNEAR) ) * MAXDIST;
	mycof = DDOF_MAXCOF_NEAR;
	myMAXDIST = MAXDIST;
	if (debug && e_barrier.z > 0.9) { img.y *= colorFactor; img.z *= colorFactor; } // DEBUG CYAN
}

float3 sum=tex2D(s_image,cent).rgb;
float contrib=1.h;

float blur=pow(saturate((dep-myMINDIST)/(myMAXDIST-myMINDIST)),2);

if (debug && e_barrier.x == 0.9)
{
	if (blur > 0.9) img.x *= colorFactor; // RED
	else if (blur > 0.75) img.y *= colorFactor; //GREEN
	else if (blur > 0.5) img.z *= colorFactor; // BLUE
	else if (blur > 0.25) { img.x *= colorFactor; img.y *= colorFactor; }  // DEBUG YELLOW
	else if (blur > 0.1) { img.x *= colorFactor; img.z *= colorFactor; }  // DEBUG MAGENTA
	else if (blur > 0)  { img.y *= colorFactor; img.z *= colorFactor; }  // DEBUG CYAN
}

#ifdef CONTRAST_FILTER
float3 highcontrast=img.xyz*img.xyz;
img.xyz=lerp(img.xyz,highcontrast,CONTRAST_FILTER_COEF);
#endif

#ifdef DOF_CLASSIC // use classic blur algorithm
float dof_classic_weight = 1;
if (dof_classic_weight > 0)
{
	float samples = DOF_QUALITY * DOF_OVERSAMPLING;
	sum = classicblur(cent, sum, mycof * blur * dof_classic_weight, samples);
	contrib += samples;
}
#else // use gaussian blur algorithm
float total_blur=mycof*blur*DOF_CORRECTION;
float f=0.f;
float inc=total_blur/DOF_QUALITY;
for (int i=0;i<DOF_QUALITY;i++){sum+=simpleblur(I,f);contrib++;f+=inc;}
#endif

#ifdef FORCED_SATURATION_FILTER
float gray=dot(img.xyz,float3(0.3,0.59,0.11));
img.xyz=lerp(float3(gray,gray,gray),img.xyz,COLOR_SATURATION+(dot(Ldynamic_color.xyz,float3(1,1,1))/3)*COLOR_SAT_SUN_COEF);
float3 maxc=float3(1,0.62,0);
#endif

#ifdef DEPTH_OF_FIELD
img += (sum/contrib);
half4 final = combine_bloom(img,bloom)-tex2D(s_image,I.tc0);

	#ifdef NV_FULLSCREEN
	if (e_barrier.x > 0.f && fov < ZOOM_FOV) // show NV only when red color amount > 0 and zooming
		return nv(I, final, float3(e_barrier.x, e_barrier.y, e_barrier.z), true);
	else
		return final;	
	#else
	return final;
	#endif
	
#else
return combine_bloom(img,bloom);
#endif 
}